namespace Gsl
{
    using System;
    using System.Runtime.InteropServices;

    public class Interpolation
    {
        IntPtr accel;
        IntPtr spline;
        
        [DllImport("libgsl")]
        private static extern IntPtr gsl_interp_accel_alloc();
        
        [DllImport("libgsl")]
        private static extern int gsl_spline_init(IntPtr spline, double[] xa, double[] ya, int size);
        
        [DllImport("libgsl_glue")]
        private static extern IntPtr gsl_spline_alloc_cspline(int size);
        
        [DllImport("libgsl")]
        private static extern void gsl_spline_free(IntPtr spline);
        
        [DllImport("libgsl")]
        private static extern void gsl_interp_accel_free(IntPtr accel);
        
        public Interpolation(double[] x, double[] y)
        {
            if (x.Length != y.Length || x.Length == 0)
            {
                throw new GslException("Interpolation error:  arrays not the same length or are zero length", Error.Code.GSL_FAILURE);
            }
            
            accel = gsl_interp_accel_alloc();
            spline = gsl_spline_alloc_cspline(x.Length);
            gsl_spline_init(spline, x, y, x.Length);
        }
        
        ~Interpolation()
        {
            gsl_spline_free(spline);
            gsl_interp_accel_free(accel);
        }
        
        [DllImport("libgsl")]
        private static extern double gsl_spline_eval(IntPtr spline, double x, IntPtr accel);
        
        public double Eval(double x)
        {
            return gsl_spline_eval(spline, x, accel);
        }
    }
}
